use std::collections::HashMap;
use std::fs::File;
use std::io::{BufReader, Read};
use std::path::{Path, PathBuf};
use std::{fs, io};
use xml::reader::XmlEvent;
use xml::EventReader;

///读取帮助文件
pub fn read_help_file(file_name: &str) -> io::Result<()> {
    let base_path = PathBuf::from("./configs/help");
    let help_file_name = base_path.join(file_name);
    let mut help_file = std::fs::File::open(help_file_name)?;
    let mut help_info = String::new();
    help_file.read_to_string(&mut help_info)?;
    println!("{}", help_info);
    Ok(())
}

///创建目录
pub fn create_dir_with_complete_path(complete_dir_path: &str) -> io::Result<()> {
    fs::create_dir_all(complete_dir_path)?;
    Ok(())
}

///拷贝目录
pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
    fs::create_dir_all(&dst)?;
    for entry in fs::read_dir(src)? {
        let entry = entry?;
        let ty = entry.file_type()?;
        if ty.is_dir() {
            copy_dir_all(entry.path(), dst.as_ref().join(entry.file_name()))?;
        } else {
            fs::copy(entry.path(), dst.as_ref().join(entry.file_name()))?;
        }
    }
    Ok(())
}

pub fn is_dir_exists(path: &str) -> bool {
    let path = Path::new(path);
    if let Ok(metadata) = fs::metadata(path) {
        metadata.is_dir()
    } else {
        false
    }
}

pub fn is_file(path: &str) -> bool {
    match fs::metadata(path) {
        Ok(meta) => meta.is_file(),
        Err(_) => false,
    }
}

pub fn read_toolchain_config(xml_path: &str) -> io::Result<Vec<HashMap<String, String>>> {
    let xml_file = File::open(xml_path)?;
    let buffer_reader = BufReader::new(xml_file);
    let parser = EventReader::new(buffer_reader);
    let mut toolchains = Vec::new();
    for e in parser {
        match e {
            Ok(XmlEvent::StartElement {
                name, attributes, ..
            }) => match name.local_name.as_str() {
                "toolchain" => {
                    let mut toolchain_map = HashMap::new();
                    for item in attributes {
                        toolchain_map.insert(item.name.local_name, item.value);
                    }
                    toolchains.push(toolchain_map);
                }
                _ => {}
            },
            Ok(XmlEvent::EndElement { name }) => {}
            Err(e) => {
                eprintln!("Error: {e}");
                break;
            }
            _ => {}
        }
    }
    Ok(toolchains)
}
